//
//  LinkedListImplementaionView.swift
//  DataStructure
//
//  Created by kys-20 on 2019/8/27.
//  Copyright © 2019 kys-20. All rights reserved.
//

enum pathStyle {
    case isometricSlash//等距斜线
    case translation//平移
    case noIsometricSlash//非等距斜线
}


import Foundation
import UIKit

let lableWIDTH = (UIScreen.main.bounds.width-(2*36+3*20))/4
let lableHEIGHT = lableWIDTH*(40/70)
class LinkedListImplementaionView :UIView{
    
    let textField = UITextField()//输入框
    let buttonPush = UIButton()//push按钮
    let buttonPop = UIButton()//pop按钮
    let buttonClear = UIButton()//Clearn按钮
    let tagNumLable = UILabel()//标记出链表的值或进链表的值
    let numLabel = UILabel() // 显示要操作的值 可移动
    let slider = UISlider()//滑块 用来控制时间
    
    let vi = UIView()//用于展示直线
    
    var numTimeTwo : Double = 0.00//用于控制按钮是否可点击
    
    var num = 0//元素个数
    var sTimeArray  = [Double]()//用来计时
    var sumTime : Double = 2.00 // 总时间
    var unitDistance : Double = 0.0//单位距离 根据总时间和总距离所得
//    var timeNum : Int = 0
    
    let topTitle = UILabel()
    let topLable = UILabel()
    var lableArray = [UILabel]()
    
    var timeOne : Timer!//计时器
    var timeTwo : Timer!//控制按钮是否可点击的计时器
    
    var pathArray = [UIBezierPath]()
    var shapeLayerArray = [CAShapeLayer]()
    //最后label的斜线
    var path : UIBezierPath!
    var shapeLayer : CAShapeLayer!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        vi.frame = self.bounds
        self.addSubview(vi)
        
        setUpUi()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func setUpUi(){
        
        slider.frame = CGRect(x: 10, y: UIScreen.main.bounds.height-60, width: UIScreen.main.bounds.width-20, height: 30)
        slider.minimumValue = 0
        slider.maximumValue = 4
        slider.value = 2.00
        self.addSubview(slider)
        slider.isContinuous = false//滑块滑动停止后才触发ValueChanged事件
        slider.addTarget(self, action: #selector(ActionSliderValueChange), for: .valueChanged)
        
        
        textField.frame = CGRect(x: 20, y: 100, width: 70, height: 40)
        textField.borderStyle = .roundedRect
        textField.layer.borderColor = UIColor.red.cgColor
        textField.layer.borderWidth = 1
        self.addSubview(textField)
        buttonPush.frame = CGRect(x: 100, y: 100, width: 70, height: 40)
        buttonPush.setTitle("Push", for: .normal)
        buttonPush.setTitleColor(UIColor.black, for: .normal)
        buttonPush.backgroundColor = UIColor.white
        buttonPush.layer.borderWidth = 1
        self.addSubview(buttonPush)
        buttonPush.addTarget(self, action: #selector(ActionPush), for: .touchUpInside)
        
        buttonPop.frame = CGRect(x: 180, y: 100, width: 70, height: 40)
        buttonPop.setTitle("Pop", for: .normal)
        buttonPop.setTitleColor(UIColor.black, for: .normal)
        buttonPop.backgroundColor = UIColor.white
        buttonPop.layer.borderWidth = 1
        buttonPop.addTarget(self, action: #selector(ActionPop), for: .touchUpInside)
        self.addSubview(buttonPop)
        
        buttonClear.frame = CGRect(x: 260, y: 100, width: 100, height: 40)
        buttonClear.setTitle("Clear Stack", for: .normal)
        buttonClear.setTitleColor(UIColor.black, for: .normal)
        buttonClear.backgroundColor = UIColor.white
        buttonClear.layer.borderWidth = 1
        buttonClear.addTarget(self, action: #selector(ActionClear), for: .touchUpInside)
        self.addSubview(buttonClear)
        
        topLable.frame = CGRect(x: 40, y: 185, width: 40, height: 40)
        topLable.backgroundColor = UIColor.white
        topLable.layer.borderColor = UIColor.black.cgColor
        topLable.layer.borderWidth = 1
        self.addSubview(topLable)
        
        tagNumLable.frame = CGRect(x: 20, y: 145, width: 80, height: 30)
        tagNumLable.font = UIFont.systemFont(ofSize: 12)
        tagNumLable.backgroundColor = UIColor.white
        tagNumLable.textColor = UIColor.black
        
        tagNumLable.isHidden = true
        self.addSubview(tagNumLable)
        
        numLabel.frame = CGRect(x: 100, y: 145, width: lableWIDTH, height: 30)
        numLabel.backgroundColor = UIColor.clear
        numLabel.textAlignment = .center
        numLabel.textColor = UIColor.black
        numLabel.font = UIFont.systemFont(ofSize: 14)
        numLabel.isHidden = true
        self.addSubview(numLabel)
        
//        setFirstLabelLine()
        
    }
    
    @objc func ActionSliderValueChange(){
        if Double(slider.value) <= 0.0001{
            sumTime = 0.0001
        }else{
            sumTime = Double(slider.value)
        }
        
    }
    //创建直线 利用贝塞尔曲线
    func set(){
        let path = UIBezierPath()
        let shapeLayer = CAShapeLayer()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: 0, y: 0))
        path.close()
        
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 1
        shapeLayer.lineJoin = CAShapeLayerLineJoin.round
        shapeLayer.lineCap = CAShapeLayerLineCap.round
        shapeLayer.path = path.cgPath
        shapeLayer.strokeStart = 0
        shapeLayer.strokeEnd = 1
        vi.layer.addSublayer(shapeLayer)
        shapeLayerArray.append(shapeLayer)
        pathArray.append(path)
    }

    
    //    Clear Stack按钮事件
    @objc func ActionClear(){
        for i in pathArray{
            i.removeAllPoints()
        }
        for i in shapeLayerArray{
            i.path = nil
        }
        for i in lableArray{
            i.isHidden = true
        }
        lableArray.removeAll()
        num = 0
    }
    //push按钮事件
    @objc func ActionPush(){
        if textField.text != ""{
            setlable()
            accordingPush()
            //             sleep(1)
            numMove()
            buttonIsEnabledFalse()
        }
    }
    // push显示出隐藏的lable:numlableAndtagNum
    func accordingPush(){
        tagNumLable.isHidden = false
        numLabel.isHidden = false
        tagNumLable.text = "Pushing Value"
        numLabel.text = textField.text
        textField.text = ""
    }
    //数字移动动画
    func numMove(){
        UIView.animate(withDuration: sumTime, animations: {
            self.numLabel.center.x = self.lableArray[self.num-1].center.x
            self.numLabel.center.y = self.lableArray[self.num-1].center.y
        }) { (_) in
            self.tagNumLable.isHidden = true
            self.numLabel.isHidden = true
            self.numLabel.frame = CGRect(x: 110, y: 80, width: 50, height: 10)
            self.lableArray[self.num-1].text = self.numLabel.text
            self.lableArray[self.num-1].backgroundColor = UIColor.white
            self.star()
        }
    }
    //    计时开始
    func star(){
        timeOne = Timer.scheduledTimer(timeInterval: 0.0001, target: self, selector: #selector(actionIsometricSlash), userInfo: nil, repeats: true)
        timeTwo = Timer.scheduledTimer(timeInterval: 0.0001, target: self, selector: #selector(actionButtonIsEnabled), userInfo: nil, repeats: true)
        
    }
    
    @objc func actionButtonIsEnabled(){
        numTimeTwo = numTimeTwo + 0.0001
        if numTimeTwo >= sumTime {
            numTimeTwo = 0.00
            buttonIsEnabledTrue()
            timeTwo.invalidate()
        }
    }
    //动画开始
    @objc func actionIsometricSlash(){
          //++++++++++++++++数组中最后一个label 斜线
//                      path.removeAllPoints()
//                      path.move(to: CGPoint(x: lableArray[0].frame.origin.x + (3/4)*lableWIDTH, y: lableArray[0].frame.origin.y) )
//                      path.addLine(to: CGPoint(x: lableArray[0].frame.maxX, y: lableArray[0].frame.maxY))
//
//                      shapeLayer.path = path.cgPath
         //++++++++++++++++
        for i in 1...num{
            if i == num {
                moveLable(type: .isometricSlash, label: lableArray[num-1])
                sTimeArray[num-1] =  sTimeArray[num-1] + 0.0001
                if sTimeArray[num-1] >= sumTime{
                    timeOne.invalidate()
                    sTimeArray[num-1] = 0.00
                }
            }else if (num - i)%4 == 0{
                moveLable(type:.noIsometricSlash, label: lableArray[i-1])
                sTimeArray[i-1] =  sTimeArray[i-1] + 0.0001
                if sTimeArray[i-1] >= sumTime{
                    timeOne.invalidate()
                    sTimeArray[i-1] = 0.00
                }
            }
            else {
                moveLable(type:.translation, label: lableArray[i-1])
                sTimeArray[i-1] =  sTimeArray[i-1] + 0.0001
                if sTimeArray[i-1] >= sumTime{
                    timeOne.invalidate()
                    sTimeArray[i-1] = 0.00
                }
            }
            pathArray[0].removeAllPoints()
            pathArray[0].move(to: topLable.center)
            pathArray[0].addLine(to: lableArray[num-1].center)
            shapeLayerArray[0].path = pathArray[0].cgPath
            
            if i >= 2{
                pathArray[i-1].removeAllPoints()
                pathArray[i-1].move(to: lableArray[i-1].center)
                pathArray[i-1].addLine(to: lableArray[i-2].center)
                shapeLayerArray[i-1].path = pathArray[i-1].cgPath
            }
        }
    }

    func setlable(){
        let label = CustomLabel()
        label.frame = CGRect(x:180, y: 161, width: lableWIDTH, height: lableHEIGHT)
        lableArray.append(label)
        self.addSubview(label)
        num = num + 1
        sTimeArray.append(0.00)
        set()//绘制直线
      
        
     
    }
    
    func moveLable(type:pathStyle,label:UILabel){
        switch type {
        case .isometricSlash:
            let x = label.frame.origin.x - CGFloat(144/(10000*sumTime))
            let y = label.frame.origin.y + CGFloat(144/(10000*sumTime))
            let w = label.frame.size.width
            let h = label.frame.size.height
            label.frame = CGRect(x: x, y: y, width: w, height: h)
        case .translation:
            let x = label.frame.origin.x + CGFloat((20+Double(lableWIDTH))/(10000*sumTime))
            let y = label.frame.origin.y
            let w = label.frame.size.width
            let h = label.frame.size.height
            label.frame = CGRect(x: x, y: y, width: w, height: h)
        default:
            let w = label.frame.size.width
            let h = label.frame.size.height
            let x = label.frame.origin.x - CGFloat((3*Double(lableWIDTH)+60)/(10000*sumTime))
            let y = label.frame.origin.y + (40+h) / CGFloat((10000*sumTime))
            //((120+h)*CGFloat((3*Double(lableWIDTH)+60)/(100*sumTimer)))/((120+h)/(3*w+60)) //(120+h)/(3*w+60)/CGFloat((3*Double(lableWIDTH)+60)/(100*sumTimer))
            label.frame = CGRect(x: x, y: y, width: w, height: h)
        }
     
        
    }
    
    @objc func ActionPop(){
        if num >= 1{
            buttonIsEnabledFalse()
            pathArray[num-1].removeAllPoints()
            shapeLayerArray[num-1].path = pathArray[num-1].cgPath
            lableArray[num-1].isHidden = true
            pathArray.remove(at: num-1)
            shapeLayerArray.remove(at: num-1)
            lableArray.remove(at: num-1)
            num = num - 1
            if num >= 1{
                pathArray[0].removeAllPoints()
                pathArray[0].move(to: topLable.center)
                pathArray[0].addLine(to: lableArray[num-1].center)
                shapeLayerArray[0].path = pathArray[0].cgPath
                starPop()
            }
            timeTwo = Timer.scheduledTimer(timeInterval: 0.0001, target: self, selector: #selector(actionButtonIsEnabled), userInfo: nil, repeats: true)
        }
    }
    
    func starPop(){
        timeOne = Timer.scheduledTimer(timeInterval: 0.0001, target: self, selector: #selector(actionIsometricSlashPop), userInfo: nil, repeats: true)
    }
    //动画开始
    @objc func actionIsometricSlashPop(){

        for i in 1...num{
            if (num + 1 - i)%4 == 0 && num != i{
                moveLablePop(type:.noIsometricSlash, label: lableArray[i-1])
                sTimeArray[i-1] =  sTimeArray[i-1] + 0.0001
                if sTimeArray[i-1] >= sumTime{
                    timeOne.invalidate()
                    sTimeArray[i-1] = 0.00
                }
            }else{
                moveLablePop(type: .translation, label: lableArray[i-1])
                sTimeArray[i-1] =  sTimeArray[i-1] + 0.0001
                if sTimeArray[i-1] >= sumTime{
                    timeOne.invalidate()
                    sTimeArray[i-1] = 0.00
                }
            }
       
            pathArray[0].removeAllPoints()
            pathArray[0].move(to: topLable.center)
            pathArray[0].addLine(to: lableArray[num-1].center)
            shapeLayerArray[0].path = pathArray[0].cgPath
             
            if i >= 2{
                pathArray[i-1].removeAllPoints()
                pathArray[i-1].move(to: lableArray[i-1].center)
                pathArray[i-1].addLine(to: lableArray[i-2].center)
                shapeLayerArray[i-1].path = pathArray[i-1].cgPath
            }
        }
    }
    
    func moveLablePop(type:pathStyle,label:UILabel){
        switch type {
        case .isometricSlash:
            let x = label.frame.origin.x - CGFloat(144/(10000*sumTime))
            let y = label.frame.origin.y + CGFloat(144/(10000*sumTime))
            let w = label.frame.size.width
            let h = label.frame.size.height
            label.frame = CGRect(x: x, y: y, width: w, height: h)
        case .translation:
            let x = label.frame.origin.x - CGFloat((20+Double(lableWIDTH))/(10000*sumTime))
            let y = label.frame.origin.y
            let w = label.frame.size.width
            let h = label.frame.size.height
            label.frame = CGRect(x: x, y: y, width: w, height: h)
        default:
            let w = label.frame.size.width
            let h = label.frame.size.height
            let x = label.frame.origin.x + CGFloat((3*Double(lableWIDTH)+60)/(10000*sumTime))
            let y = label.frame.origin.y -  (40+h) / CGFloat((10000*sumTime))
            label.frame = CGRect(x: x, y: y, width: w, height: h)
        }
    }
    //button可点击或不可点击
    func buttonIsEnabledFalse(){
        buttonPop.isEnabled = false
        buttonPush.isEnabled = false
        buttonClear.isEnabled = false
        slider.isEnabled = false
    }
    func buttonIsEnabledTrue(){
        buttonPop.isEnabled = true
        buttonPush.isEnabled = true
        buttonClear.isEnabled = true
        slider.isEnabled = true
    }
    
}
